from typing import Any
import jinja2 as jj2
import pathlib

# from .Content import get_content
from . import global_vars

g_current_path = pathlib.Path(__file__).parent.absolute()


class RenderContext:

    def __init__(self, output_file) -> None:
        self.output_file = pathlib.Path(output_file)
        self.output_dir = pathlib.Path(self.output_file).parent


class Template:
    __g_task_context = None

    def __init__(self, name: str, env: jj2.Environment = None) -> None:
        self.name = name
        self.env = env
        self.__kws = {}
        self._template_base_path = '.'

        self.tasks = []
        self._jinja_env_kws = {}

    def set_var(self, var_name: str, obj: Any):
        # value = get_content(obj) or obj
        self.__kws[var_name] = obj

    def set_vars(self, **kws):
        for k, w in kws.items():
            self.set_var(k, w)

    @property
    def template_base_path(self):
        return self._template_base_path

    @template_base_path.setter
    def template_base_path(self, value):
        self._template_base_path = value

    def set_env_args(self, **jinja_env_kws):
        self._jinja_env_kws = jinja_env_kws

    def set_task(self, func):
        self.tasks.append(func)

    def render(self) -> str:
        env = self.env or jj2.Environment(**self._jinja_env_kws,
                                          loader=jj2.FileSystemLoader(self.template_base_path))

        tl = env.get_template(self.name)

        return tl.render(**self.__kws)

    @staticmethod
    def _reset_task_context(file):
        ctx = RenderContext(file)
        Template.__g_task_context = ctx

    def to_file(self, file):
        Template._reset_task_context(file)
        with open(file, 'w', encoding='utf8') as f:
            f.write(self.render())

    def run_tasks(self):
        for t in self.tasks:
            t(Template.__g_task_context)

    def __str__(self):

        res = self.render()
        self.run_tasks()
        return res

    def __repr__(self) -> str:
        return self.__str__()

    @staticmethod
    def _create_by_libs_env(name: str):
        return Template(name, global_vars.create_jj2_env_libs())
